package com.partsoft.dits.integrate;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;

import com.partsoft.dits.DescriptorDepends;
import com.partsoft.dits.EdgeDescriptor;

public class BaseDescriptorDependsManager implements DescriptorDepends<EdgeDescriptor> {
	
	private Set<DescriptorDepends<EdgeDescriptor>> depends = Collections.synchronizedSet(new HashSet<DescriptorDepends<EdgeDescriptor>>(5));
	
	public void addDescriptorDepends(DescriptorDepends<EdgeDescriptor> descs) {
		Assert.notNull(descs);
		Assert.isTrue(!ObjectUtils.nullSafeEquals(this, descs), "不能添加自己。");
		depends.add(descs);
	}
	
	public void removeDescriptorDepends(DescriptorDepends<EdgeDescriptor> descs) {
		Assert.notNull(descs);
		depends.remove(descs);
	}
	
	protected void clearDescriptorDepends() {
		depends.clear();
	}

	public Set<Class<? extends EdgeDescriptor>> getDependClasses() {
		Set<Class<? extends EdgeDescriptor>> classes = new LinkedHashSet<Class<? extends EdgeDescriptor>>();
		for (DescriptorDepends<EdgeDescriptor> dep : depends) {
			classes.addAll(dep.getDependClasses());
		}
		return Collections.unmodifiableSet(new HashSet<Class<? extends EdgeDescriptor>>(classes));
	}

	public boolean dependDescriptor(EdgeDescriptor descriptor) {
		boolean result = false;
		if (getDependClasses().contains(ClassUtils.getUserClass(descriptor))) {
			for (DescriptorDepends<EdgeDescriptor> dep : depends) {
				result = dep.dependDescriptor(descriptor);
				if (result) break;
			}
		}
		return result;
	}

	public EdgeDescriptor[] getDescriptorByDepend(EdgeDescriptor descriptor) {
		EdgeDescriptor returnArray[] = new EdgeDescriptor[0];
		if (dependDescriptor(descriptor)) {
			List<EdgeDescriptor> returnList = new LinkedList<EdgeDescriptor>();
			for (DescriptorDepends<EdgeDescriptor> dep : depends) {
				if (dep.dependDescriptor(descriptor)) {
					returnList.addAll(Arrays.asList(dep.getDescriptorByDepend(descriptor)));
				}
			}
			returnArray = returnList.toArray(returnArray);
		}
		return returnArray;
	}
}
